<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8"/>
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"/>
        <title>AJ Framework-统一异常</title>
        <meta name="description" content="AJ Framework 一个基于 SpringMVC 构建的轻量级框架，旨在增强 SpringMVC 并使其更具 SpringBoot 的特性。它拥有许多小型组件，非常易于使用。" />
        <meta name="keywords" content="AJ Framework, ajaxjs, ajaxjs framework, java framework, web framework" />
        <meta name="viewport" content="width=device-width, initial-scale=1"/>
        <link rel="preconnect" href="https://fonts.googleapis.com" />
        <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
        <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@200..900&family=Noto+Serif:ital,wght@0,100..900;1,100..900&display=swap&family=Noto+Sans+SC:wght@100..900&display=swap" />
        <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@100..900&family=Noto+Serif:ital,wght@0,100..900;1,100..900&display=swap" /> 
        <link rel="stylesheet" href="https://framework.ajaxjs.com/static/new-ui/css/common.css" />
        <link rel="stylesheet" href="https://iam.ajaxjs.com/asset/main.css"/>
        <link rel="icon" type="image/x-icon" href="https://framework.ajaxjs.com/aj-logo/logo.ico"/>
        <script src="https://framework.ajaxjs.com/static/aj-docs/common.js"></script>
        <script>
            var _hmt = _hmt || [];
            (function() {
              var hm = document.createElement("script");
              hm.src = "https://hm.baidu.com/hm.js?a3dec1d9b9415edd86b54c1fb3d02f19";
              var s = document.getElementsByTagName("script")[0];
              s.parentNode.insertBefore(hm, s);
            })();
        </script>
    </head>
    <body>
        <nav>
            <div>
                <div class="links">
                    <a href="/">🏠 首页</a>
                    | ⚙️ 源码:
                    <a target="_blank" href="https://github.com/lightweight-component/aj-framework">Github</a>/<a target="_blank" href="https://gitcode.com/lightweight-component/aj-framework">Gitcode</a>
                    |
                    <a href="/common/contact">✉️ 联系</a>
                </div>
                <h1>
                    <img src="https://framework.ajaxjs.com/aj-logo/logo.png" style="vertical-align: middle;height: 45px;margin-bottom: 6px;" />
                    AJ Framework
                </h1>
                <h3>轻量级 Java 快速开发框架
                </h3>
            </div>
        </nav>
        <div>
            <menu>
                
                <ul>
                    <li class="selected">
                        <a href="/">首页</a>
                    </li>
                </ul>
                <h3>框架基本用法</h3>
                <ul>
                    <li>
                        <a href="/framework/init">初始化一个项目</a>
                    </li>
                    <li>
                        <a href="/framework/controller">简化控制器为接口</a>
                    </li>
                    <li>
                        <a href="/framework/unified-return">统一对象返回</a>
                    </li>
                    <li>
                        <a href="/framework/unified-ex">统一异常处理</a>
                    </li>
                    <li>
                        <a href="/framework/package">打包与部署</a>
                    </li>
                </ul>
                <h3>常用组件</h3>
                <ul>
                    <li>
                        <a href="/component/db">数据库访问</a>
                    </li>
                    <li>
                        <a href="/component/bean-validator/">Bean 实体校验</a>
                    </li>
                    <li>
                        <a href="/component/security">安全组件、用户系统</a>
                    </li>
                    <li>
                        <a href="/component/lite-c/">使用简单本地缓存</a>
                    </li>
                  <li>
                       <a href="/component/cache/">使用多级缓存</a>
                   </li>
                </ul>

                <h3>其他</h3>
                <ul>
                    <li><a href="/common/contact">联系</a></li>
                </ul>
            </menu>
            <article class="aj-text chinese">
                <h1>统一异常处理</h1>
<h2>使用全局异常处理器</h2>
<p>有些小伙伴，经常喜欢在 Controller、Service 代码中捕获异常。不管是普通异常 Exception，还是运行时异常 RuntimeException，都使用<code>try/catch</code>把它们捕获。
反例：</p>
<pre><code class="language-java">try {
    checkParam(param);
} catch (BusinessException e) {
    return ApiResultUtil.error(1,&quot;参数错误&quot;);
}
</code></pre>
<p>显然这种做法会造成大量重复的代码。我们在 Controller、Service 等业务代码中，尽可能少捕获异常。这种业务异常处理，应该交给拦截器统一处理。有了这个全局的异常处理器，之前我们在 Controller 或者 Service 中的<code>try/catch</code>代码可以去掉。</p>
<p>如果在接口中出现异常，全局的异常处理器<code>HandlerExceptionResolver</code>会帮我们封装结果，返回给用户。具体实现请看<span class="external-link">
<span>↗</span>
</span><a href="https://gitcode.com/zhangxin09/aj-framework/blob/master/aj-framework/src/main/java/com/ajaxjs/springboot/GlobalExceptionHandler.java"><code>GlobalExceptionHandler</code></a>，非常简单。所有异常到跑到这里来打印，根据具体的异常返回特定的 HTTP Status Code，比如 <code>SecurityException</code>、<code>IllegalAccessError</code>、<code>IllegalAccessException</code> 返回 403。</p>
<h2>优先使用标准异常</h2>
<p>在 Java 中已经定义了许多比较常用的标准异常，比如下面这张图中列出的这些异常。</p>
<ul>
<li><code>IllegalArgumentException</code> 入参不合法</li>
<li><code>IllegalStateException</code> 入参的状态不合法</li>
<li><code>UnsupportedOperationException</code> 不支持的操作</li>
<li><code>SecurityException</code> 安全异常 返回 401/403</li>
<li><code>NullPointerException</code> 空指针异常 返回 500</li>
</ul>
<p>反例：</p>
<pre><code class="language-java">public void checkValue(int value) {
    if (value &lt; 0) {
        throw new MyIllegalArgumentException(&quot;值不能为负&quot;);
    }
}
</code></pre>
<p>自定义了一个异常表示参数错误。其实我们可以直接复用已有的标准异常。</p>
<p>正例：</p>
<pre><code class="language-java">public void checkValue(int value) {
    if (value &lt; 0) {
        throw new IllegalArgumentException(&quot;值不能为负&quot;);
    }
}
</code></pre>
<h2>尽可能捕获具体异常</h2>
<p>在你的业务逻辑方法中，有可能需要去处理多种不同的异常。 你可能你会觉得比较麻烦，而直接捕获<code>Exception</code>。</p>
<p>反例：</p>
<pre><code class="language-java">try {
    doSomething();
} catch(Exception e) {
    log.error(&quot;doSomething处理失败，原因：&quot;,e);
}
</code></pre>
<p>这样捕获异常太笼统了。 其实<code>doSomething</code>方法中，会抛出<code>FileNotFoundException</code>和<code>IOException</code>。 这种情况我们最好捕获具体的异常，然后分别做处理。</p>
<p>正例：</p>
<pre><code class="language-java">try {
   doSomething();
} catch(FileNotFoundException e) {
  log.error(&quot;doSomething处理失败，文件找不到，原因：&quot;,e);
} catch(IOException e) {
  log.error(&quot;doSomething处理失败，IO出现了异常，原因：&quot;,e);
}
</code></pre>
<p>这样如果后面出现了上面的异常，我们就非常方便知道是什么原因了。</p>

            </article>
        </div>
        <footer>
             开源框架 <a href="https://framework.ajaxjs.com" target="_blank">AJ-Framework</a> 首页。联系方式：
             frank@ajaxjs.com，<a href="https://blog.csdn.net/zhangxin09" target="_blank">作者博客</a>
             <br />
             <br />
             Copyright © 2025 Frank Cheung. All rights reserved.
         </footer>
    </body>
</html>